with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Streams; use Ada.Streams;
with Ada.Containers.Hashed_Maps;
With Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Interfaces; use Interfaces;
with IO;
package Element is

   type Element_Content_Type is (SIGNED_INTEGER, UNSIGNED_INTEGER, FLOAT, ASCII_STRING, UTF_8_STRING, DATE, BINARY, CONTAINER);

--     type Element_ID_Type_A is mod 2**7;
--     procedure Read_ID_A(Stream : not null access Ada.Streams.Root_Stream_Type'Class; Item : out Element_ID_Type_A);
--     for Element_ID_Type_A'Read use Read_ID_A;
--
--     type Element_ID_Type_B is mod 2**14;
--     type Element_ID_Type_C is mod 2**21;
--     type Element_ID_Type_D is mod 2**28;

   type Element_ID_Type is new Unsigned_32;
   procedure Read_Element_ID_Type(Stream : not null access Ada.Streams.Root_Stream_Type'Class; Item : out Element_ID_Type);
   for Element_ID_Type'Read use Read_Element_ID_Type;

   --type Element_Size_Type is range 0 .. (2**56)-2;
   type Element_Size_Type is mod 2 ** 56;
   for Element_Size_Type'Size use 64;
   procedure Read_Element_Size_Type(Stream : not null access Ada.Streams.Root_Stream_Type'Class; Item : out Element_Size_Type);
   for Element_Size_Type'Read use Read_Element_Size_Type;

   Element_ID_Exception : exception;
   Element_Size_Exception : exception;

   type EBML_Element_Type is record
      ID : Element_ID_Type := 0;
      Description : Unbounded_String;
      Content : Element_Content_Type;
   end record;
   type EBML_Element_Type_Access is access all EBML_Element_Type;

   function ID_Hashed (id: Element_ID_Type) return Ada.Containers.Hash_Type;

   package EBML_Element_Type_Map is new Ada.Containers.Hashed_Maps
     (Key_Type => Element_ID_Type,
      Element_Type => EBML_Element_Type_Access,
      Hash => ID_Hashed,
      Equivalent_Keys => "=");

   EBML_Element_Map : EBML_Element_Type_Map.Map;

   type Element_Type is tagged record
      ID : Element_ID_Type := 0;
      Size : Element_Size_Type := 0;
      File_Index : Positive_Count;
      Depth : Positive;
      EBML_Type : EBML_Element_Type_Access;
   end record;
   procedure Read_Element_Type(Stream : not null access Ada.Streams.Root_Stream_Type'Class; Item : out Element_Type);
   for Element_Type'Read use Read_Element_Type;
   function File_End_Index (ET : in Element_Type) return Positive_Count;
   function Value(ET : Element_Type; File : IO.File_Type_Access) return Element_Size_Type;

   NULL_Element_Type : Element_Type := (0,0,1,1,null);


private
   pragma Inline(File_End_Index);
   pragma Inline(ID_Hashed);

end Element;